package server.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.ObservableList;

public class SocketServer {

	private static final String CLOSE = "close";// 断开标志
	private ServerSocket server;// 服务器

	private SimpleStringProperty receMsg;// 发送消息

	private HashMap<String, SocketHandeler> clients = new HashMap<>();// 处理客户请求socket
	private ObservableList<String> ipList;// 客户ip列表

	private SimpleDateFormat time = new SimpleDateFormat("yy-MM-dd HH:mm:ss");

	public SocketServer(SimpleStringProperty receMsg, ObservableList<String> ipList) {
		this.receMsg = receMsg;
		this.ipList = ipList;
	}

	/**
	 * 启动服务器
	 * 
	 * @return
	 */
	public boolean start() {
		try {
			server = new ServerSocket(888);
			new Thread() {
				@Override
				public void run() {
					while (true) {
						Socket socket;
						try {
							socket = server.accept();
							String ip = socket.getInetAddress().toString().substring(1);
							receMsg.set(ip + ":" + socket.getPort() + " connetced...\n");
							Platform.runLater(() -> {
								ipList.add(ip + ":" + socket.getPort());
							});
							SocketHandeler socketHandeler = new SocketHandeler(socket);
							clients.put(ip + ":" + socket.getPort(), socketHandeler);
							socketHandeler.start();
						} catch (IOException e) {
							// e.printStackTrace();
							break;
						}

					}

				}
			}.start();
			return true;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}

	}

	/**
	 * 关闭服务器
	 * 
	 * @return
	 */
	public boolean close() {
		for (int i = 0; i < clients.size(); i++) {
			clients.get(ipList.get(i)).sendMessage(CLOSE);
			clients.get(ipList.get(i)).close();
		}
		try {
			server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return true;
	}

	/**
	 * 向客户端发送消息
	 * 
	 * @param list
	 * @param msg
	 */
	public void sendMessage(List<String> list, String msg) {
		for (int i = 0; i < list.size(); i++) {
			SocketHandeler socketHandeler = clients.get(list.get(i));
			if (socketHandeler != null) {
				socketHandeler.sendMessage(msg);
				receMsg.set(time.format(new Date()) + " " + "To:" + list.get(i) + "\n" + msg.trim() + "\n");
			}
		}

	}

	/**
	 * 处理客户端连接
	 * 
	 * @author huangyk
	 *
	 */

	class SocketHandeler extends Thread {
		private Socket socket;
		private String ip;

		private BufferedReader reader;
		private BufferedWriter writer;

		public SocketHandeler(Socket socket) {
			this.socket = socket;
			this.ip = socket.getInetAddress().toString().substring(1) + ":" + socket.getPort();
			try {
				this.reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
				this.writer = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			try {
				while (true) {
					String line = reader.readLine();
					if (line != null) {
						if (line.trim().equals(CLOSE)) {
							// System.out.println("客户端已断开");
							close();
							break;
						}
						synchronized (receMsg) {
							receMsg.set(time.format(new Date()) + " " + "From:" + ip + "\n" + line + "\n");
						}
					}
				}
			} catch (IOException e) {
				// e.printStackTrace();
				// System.out.println("客户端已断开");
				close();
			}

		}

		/**
		 * 断开连接
		 */
		public void close() {
			try {
				socket.close();
				reader.close();
				socket.close();
				Platform.runLater(() -> {
					for (int i = 0; i < ipList.size(); i++) {
						if (ipList.get(i).contains(socket.getPort() + "")) {
							clients.remove(ipList.get(i));
							ipList.remove(i);
							break;
						}
					}
				});
				synchronized (receMsg) {
					receMsg.set(ip + " disconnected..." + "\n");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		/**
		 * 发送消息
		 * 
		 * @param msg
		 */
		public void sendMessage(String msg) {
			try {
				writer.write(msg, 0, msg.length());
				writer.newLine();
				writer.flush();

			} catch (IOException e) {
				e.printStackTrace();
			}

		}

	}

}
